# -*- coding: utf-8 -*-

from django.forms.models import ModelFormMetaclass, ModelForm
from django.template import RequestContext, loader
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.core.xheaders import populate_xheaders
from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
from django.utils.translation import ugettext
from django.contrib.auth.views import redirect_to_login
from django.views.generic import GenericViewError
from django.contrib import messages
from django.shortcuts import render_to_response
from wal.pedidos.models import Pedido, DetallePedido
from wal.control.models import Control, Stock, Evaluacion, DetalleControl
from wal.expedicion.models import Expedicion, DetalleExpedicion
import datetime
from dateutil.relativedelta import relativedelta
def index(request):
    today = datetime.date.today()
    yesterday = today + relativedelta(days = -1)
    week = today + relativedelta(weeks = -2)
    semana = today + relativedelta(weeks = +1)
    semanas = today + relativedelta(weeks = +2)
    pedidos = Pedido.objects.filter(plazo__lte = yesterday.isoformat(), plazo__gt = week.isoformat(),finalizado = 'N')
    for p in pedidos:
        c = corregirEstado(request,p,p.fecha,p.plazo)
#     c = completarKG(request)
#    c = completarFactor(request)
#    c = corregirSuperficies(request)
#    c = correccionOT(request)
#    exp = Expedicion.objects.all()
#    for e in exp:
#        e.save()
#    con = Control.objects.all()
#    for c in con:
#        c.save()
#    ev = Evaluacion.objects.all()
#    for e in ev:
#        e.save()
    a = Pedido.objects.filter(prioridad='A',plazo__gte = today.isoformat(),plazo__lte = semanas.isoformat())
    m = Pedido.objects.filter(prioridad='M',plazo__gte = today.isoformat(),plazo__lte = semana.isoformat())
    b = Pedido.objects.filter(prioridad='B',plazo__gte = today.isoformat(),plazo__lte = semana.isoformat())
    return render_to_response('index.html',{'alta':a,'media':m,'baja':b},context_instance = RequestContext(request))

def completarKG(request):
    controles = Control.objects.all()
    for con in controles:
        detalles = DetalleControl.objects.filter(control=con,conformidad = 'C')
        kgreal = 0
        kgproc = 0
        unidades = 0
        for det in detalles:
            unidades = unidades + det.cantidad
            kgreal = kgreal + det.cantidad*det.peso
            kgproc = kgproc + det.cantidad*det.peso*det.porcentaje
        con.kgreal = kgreal
        con.kgproc = kgproc
        con.unidades = unidades
        con.save()
    return 0

def completarFactor(request):
    detalles = DetalleControl.objects.all()
    for det in detalles:
        if det.porcentaje == None:
            det.porcentaje = 1
            det.save()
    return 0

def correccionOT(request):
    #PRIMERO CORREGIR LOS PROCESOS
    pedidos = Pedido.objects.all().order_by('fecha')
    c = 1
    f = 1
    for p in pedidos:
        det = DetallePedido.objects.filter(pedido=p)[0]
        p.proceso = det.proceso
        #SEGUNDO CORREGIR OT
        if det.proceso == 'C':
            p.ot = c
            c = c + 1
        else:
            p.ot = f
            f = f + 1
        p.save()
    return 0
def correccionDeEstados(request):
    today = datetime.date.today()
    yesterday = today + relativedelta(days = -1)
    week = today + relativedelta(weeks = -2)
    pedidos = Pedido.objects.filter(plazo__lte = yesterday, plazo__gt = week,finalizado = 'N')
    for p in pedidos:
        detalle = DetallePedido.objects.filter(pedido=p)
        detcant = 0
        for item in detalle:
            detcant = detcant + item.cantidad
        stock = Stock.objects.filter(pedido=p)
        pro = 0
        des = 0
        dep = 0
        for st in stock:
            pro = pro + st.procesado
            des = des + st.despachado
            dep = dep + st.stock
            
        ban = 0
        dif = plazo - fecha
        dif = dif.days*1.1
        dif = fecha + relativedelta(days = +dif)
        
        controles = Control.objects.filter(pedido=p)
        if controles:
            for c in controles:
                if c.fecha > dif:
                    ban = 1
        elif today > dif:
            ban = 1
        
        
        if ban == 1 or (p.finalizado == 'N' and dif < today):
            if detcant == des:
                p.finalizado = 'G'
            elif detcant == des + dep:
                p.finalizado = 'I'
            elif pro == 0 and p.finalizado == 'C':
                p.finalizado = 'C'
            elif detcant > pro:
                p.finalizado = 'M'
        else:
            if detcant == des:
                p.finalizado = 'F'
            elif detcant == des + dep:
                p.finalizado = 'H'
            elif pro == 0 and p.finalizado == 'C':
                p.finalizado = 'C'
            elif detcant > pro:
                p.finalizado = 'N'
        p.save()    
    return 0

def corregirEstado(request,p,fecha,plazo):
    today = datetime.date.today()
    detalle = DetallePedido.objects.filter(pedido=p)
    detcant = 0
    for item in detalle:
        detcant = detcant + item.cantidad
    stock = Stock.objects.filter(pedido=p)
    pro = 0
    des = 0
    dep = 0
    for st in stock:
        pro = pro + st.procesado
        des = des + st.despachado
        dep = dep + st.stock
        
    ban = 0    
    dif = plazo - fecha
    dif = dif.days*1.1
    dif = fecha + relativedelta(days = +dif)
    
    controles = Control.objects.filter(pedido=p)
    if controles:
        for c in controles:
            if c.fecha > dif:
                ban = 1
    
    
    if ban == 1 or today > dif:
        if pro == 0 and p.finalizado == 'C':
            p.finalizado = 'C'
        elif detcant > dep+des:
            p.finalizado = 'M'
    else:
        if pro == 0 and p.finalizado == 'C':
            p.finalizado = 'C'
        elif detcant >= pro:
            p.finalizado = 'N'
    p.save()    
    return 0
    
def corregirSuperficies(request):
    f = DetalleExpedicion.objects.filter(proceso='F')
    for d in f:
        if d.peso == 0:
            e = d.expedicion
            p = e.pedido
            c = Control.objects.filter(pedido=p)
            for con in c:
                det = DetalleControl.objects.filter(control=con,articulo=d.articulo,conformidad='C')
                if det:
                    det = DetalleControl.objects.filter(control=con,articulo=d.articulo,conformidad='C')[0]
                    s = Stock.objects.get(pedido=p,articulo=d.articulo)
                    if s.peso == 0:
                        s.peso = det.peso
                        s.save()
                    d.peso = det.peso*d.cantidad
                    d.save()
                    break
    return 0    

def indexDeposito(request):
    request.breadcrumbs([('Depósito',request.path)])
    return render_to_response('deposito_index.html',context_instance = RequestContext(request))

def indexGalvanizado(request):
    request.breadcrumbs([('Galvanizado',request.path)])
    return render_to_response('galvanizado_index.html',context_instance = RequestContext(request))

def split_query_into_keywords(query):
    """Split the query into keywords,
    where keywords are double quoted together,
    use as one keyword."""
    keywords = []
    # Deal with quoted keywords
    while '"' in query:
        first_quote = query.find('"')
        second_quote = query.find('"', first_quote + 1)
        quoted_keywords = query[first_quote:second_quote + 1]
        keywords.append(quoted_keywords.strip('"'))
        query = query.replace(quoted_keywords, ' ')
    # Split the rest by spaces
    keywords.extend(query.split())
    return keywords

#def apply_extra_context(extra_context, context):
#    """
#    Adds items from extra_context dict to context.  If a value in extra_context
#    is callable, then it is called and the result is added to context.
#    """
#    for key, value in extra_context.iteritems():
#        if callable(value):
#            context[key] = value()
#        else:
#            context[key] = value
#
#def get_model_and_form_class(model, form_class):
#    """
#    Returns a model and form class based on the model and form_class
#    parameters that were passed to the generic view.
#
#    If ``form_class`` is given then its associated model will be returned along
#    with ``form_class`` itself.  Otherwise, if ``model`` is given, ``model``
#    itself will be returned along with a ``ModelForm`` class created from
#    ``model``.
#    """
#    if form_class:
#        return form_class._meta.model, form_class
#    if model:
#        # The inner Meta class fails if model = model is used for some reason.
#        tmp_model = model
#        # TODO: we should be able to construct a ModelForm without creating
#        # and passing in a temporary inner class.
#        class Meta:
#            model = tmp_model
#        class_name = model.__name__ + 'Form'
#        form_class = ModelFormMetaclass(class_name, (ModelForm,), {'Meta': Meta})
#        return model, form_class
#    raise GenericViewError("Generic view must be called with either a model or"
#                           " form_class argument.")
#
#def redirect(post_save_redirect, obj):
#    """
#    Returns a HttpResponseRedirect to ``post_save_redirect``.
#
#    ``post_save_redirect`` should be a string, and can contain named string-
#    substitution place holders of ``obj`` field names.
#
#    If ``post_save_redirect`` is None, then redirect to ``obj``'s URL returned
#    by ``get_absolute_url()``.  If ``obj`` has no ``get_absolute_url`` method,
#    then raise ImproperlyConfigured.
#
#    This function is meant to handle the post_save_redirect parameter to the
#    ``create_object`` and ``update_object`` views.
#    """
#    if post_save_redirect:
#        return HttpResponseRedirect(post_save_redirect % obj.__dict__)
#    elif hasattr(obj, 'get_absolute_url'):
#        return HttpResponseRedirect(obj.get_absolute_url())
#    else:
#        raise ImproperlyConfigured(
#            "No URL to redirect to.  Either pass a post_save_redirect"
#            " parameter to the generic view or define a get_absolute_url"
#            " method on the Model.")
#
#def lookup_object(model, object_id, slug, slug_field):
#    """
#    Return the ``model`` object with the passed ``object_id``.  If
#    ``object_id`` is None, then return the object whose ``slug_field``
#    equals the passed ``slug``.  If ``slug`` and ``slug_field`` are not passed,
#    then raise Http404 exception.
#    """
#    lookup_kwargs = {}
#    if object_id:
#        lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
#    elif slug and slug_field:
#        lookup_kwargs['%s__exact' % slug_field] = slug
#    else:
#        raise GenericViewError(
#            "Generic view must be called with either an object_id or a"
#            " slug/slug_field.")
#    try:
#        return model.objects.get(**lookup_kwargs)
#    except ObjectDoesNotExist:
#        raise Http404("No %s found for %s"
#                      % (model._meta.verbose_name, lookup_kwargs))
#
#def create_object(request, model=None, template_name=None,
#        template_loader=loader, extra_context=None, post_save_redirect=None,
#        login_required=False, context_processors=None, form_class=None):
#    """
#    Generic object-creation function.
#
#    Templates: ``<app_label>/<model_name>_form.html``
#    Context:
#        form
#            the form for the object
#    """
#    if extra_context is None: extra_context = {}
#    if login_required and not request.user.is_authenticated():
#        return redirect_to_login(request.path)
#
#    model, form_class = get_model_and_form_class(model, form_class)
#    if request.method == 'POST':
#        form = form_class(request.POST, request.FILES)
#        if form.is_valid():
#            new_object = form.save()
#            
#            msg = ugettext("El/la %(verbose_name)s fue creado/a satisfactoriamente.") %\
#                                    {"verbose_name": model._meta.verbose_name}
#            messages.success(request, msg, fail_silently=True)
#            return redirect(post_save_redirect, new_object)
#    else:
#        form = form_class()
#
#    # Create the template, context, response
#    if not template_name:
#        template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
#    t = template_loader.get_template(template_name)
#    c = RequestContext(request, {
#        'form': form,
#    }, context_processors)
#    apply_extra_context(extra_context, c)
#    return HttpResponse(t.render(c))
#
#def update_object(request, model=None, object_id=None, slug=None,
#        slug_field='slug', template_name=None, template_loader=loader,
#        extra_context=None, post_save_redirect=None, login_required=False,
#        context_processors=None, template_object_name='object',
#        form_class=None):
#    """
#    Generic object-update function.
#
#    Templates: ``<app_label>/<model_name>_form.html``
#    Context:
#        form
#            the form for the object
#        object
#            the original object being edited
#    """
#    if extra_context is None: extra_context = {}
#    if login_required and not request.user.is_authenticated():
#        return redirect_to_login(request.path)
#
#    model, form_class = get_model_and_form_class(model, form_class)
#    obj = lookup_object(model, object_id, slug, slug_field)
#
#    if request.method == 'POST':
#        form = form_class(request.POST, request.FILES, instance=obj)
#        if form.is_valid():
#            obj = form.save()
#            msg = ugettext("El/la %(verbose_name)s fue actualizado/a satisfactoriamente.") %\
#                                    {"verbose_name": model._meta.verbose_name}
#            messages.success(request, msg, fail_silently=True)
#            return redirect(post_save_redirect, obj)
#    else:
#        form = form_class(instance=obj)
#
#    if not template_name:
#        template_name = "%s/%s_form.html" % (model._meta.app_label, model._meta.object_name.lower())
#    t = template_loader.get_template(template_name)
#    c = RequestContext(request, {
#        'form': form,
#        template_object_name: obj,
#    }, context_processors)
#    apply_extra_context(extra_context, c)
#    response = HttpResponse(t.render(c))
#    populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
#    return response
#
#def delete_object(request, model, post_delete_redirect, object_id=None,
#        slug=None, slug_field='slug', template_name=None,
#        template_loader=loader, extra_context=None, login_required=False,
#        context_processors=None, template_object_name='object'):
#    """
#    Generic object-delete function.
#
#    The given template will be used to confirm deletetion if this view is
#    fetched using GET; for safty, deletion will only be performed if this
#    view is POSTed.
#
#    Templates: ``<app_label>/<model_name>_confirm_delete.html``
#    Context:
#        object
#            the original object being deleted
#    """
#    if extra_context is None: extra_context = {}
#    if login_required and not request.user.is_authenticated():
#        return redirect_to_login(request.path)
#
#    obj = lookup_object(model, object_id, slug, slug_field)
#
#    if request.method == 'POST':
#        obj.delete()
#        msg = ugettext("El/la %(verbose_name)s fue borrado/a.") %\
#                                    {"verbose_name": model._meta.verbose_name}
#        messages.success(request, msg, fail_silently=True)
#        return HttpResponseRedirect(post_delete_redirect)
#    else:
#        if not template_name:
#            template_name = "%s/%s_confirm_delete.html" % (model._meta.app_label, model._meta.object_name.lower())
#        t = template_loader.get_template(template_name)
#        c = RequestContext(request, {
#            template_object_name: obj,
#        }, context_processors)
#        apply_extra_context(extra_context, c)
#        response = HttpResponse(t.render(c))
#        populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
#        return response
